﻿using System;
using System.IO;
using System.Collections.Generic;

namespace Game.Lib.CSG
{
    public class Rectangle : Shape2D
    {
        public override List<Vector> CriticalPoints
        {
            get
            {
                List<Vector> ret = new List<Vector>(5);

                ret.Add(Pos);

                Vector2 off = new Vector2(0f, Rot);

                float x = Size.X * .5f;
                float y = Size.Y * .5f;

                ret.Add(Pos + Vector2.FromPolar(new Vector2(x, y).ToPolar() + off));
                ret.Add(Pos + Vector2.FromPolar(new Vector2(-x, y).ToPolar() + off));
                ret.Add(Pos + Vector2.FromPolar(new Vector2(x, -y).ToPolar() + off));
                ret.Add(Pos + Vector2.FromPolar(new Vector2(-x, -y).ToPolar() + off));

                return ret;
            }
        }
        public override float Area
        {
            get { return Size.X * Size.Y; }
        }

        public override float Perimeter
        {
            get { return 2f * (Size.X + Size.Y); }
        }

        public Rectangle()
        {
            Pos = Size = Vector2.Zero;
            Rot = 0f;
        }

        public Rectangle(Vector2 pos, Vector2 size)
        {
            Pos = pos;
            Size = size;
        }

        public Rectangle(Vector2 pos, Vector2 size, float rot)
            : this(pos, size)
        {
            Rot = rot;
        }

        public Rectangle(Vector2 pos, float side) : this(pos, new Vector2(side)) { }

        public Rectangle(Vector2 pos, float side, float rot) : this(pos, new Vector2(side), rot) { }

        public override Rectangle GetBoundingRectangle()
        {
            if(Rot == 0f) return this;
            return new Rectangle(Pos, 2f * Vector2.FromPolar(Size.Magnitude() * .5f, Rot));
        }

        public override Ellipse GetBoundingCircle()
        {
            return new Ellipse(Pos, Size.Magnitude() * .5f);
        }

        public override bool Inside(Vector2 pos)
        {
            Vector2 min = Pos - Size * .5f;
            Vector2 max = Pos + Size * .5f;
            return pos.X > min.X && pos.X <= max.X &&
                pos.Y >= max.Y && pos.Y <= max.Y;
        }

        public override void Serialize(Stream s)
        {
            Pos.Serialize(s);
            Size.Serialize(s);
            s.Write(BitConverter.GetBytes(Rot), 0, 4);
        }

        public override void Deserialize(Stream s)
        {
            Pos.Deserialize(s);
            Size.Deserialize(s);
            byte[] buf = new byte[4];
            if (s.Read(buf, 0, 4) != 4) throw new EndOfStreamException();
            Rot = BitConverter.ToSingle(buf, 0);
        }
    }
}
